#pragma once
#include <iostream>
#include <pthread.h>
#include <functional>
#include <string>
#include <cstdint>

namespace ThreadModule
{
    std::uint32_t cnt; // 原子计数器，形成线程名称
    class Thread
    {
    public:
        
        using work_t = std::function<void()>;
        enum class TSTATUS
        {
            THREAD_NEW,
            THREAD_RUNNING,
            THREAD_STOP
        };
        Thread(work_t work) : _status(TSTATUS::THREAD_NEW),
                              _joined(true),
                              _func(work)
        {
            SetName();
        }
        void EnableJoined()
        {
            if (_status == TSTATUS::THREAD_NEW)
                _joined = true;
        }
        void EnableDetach()
        {
            if (_status == TSTATUS::THREAD_NEW)
                _joined = false;
        }
        bool Start()
        {
            if (_status == TSTATUS::THREAD_RUNNING)
                return true;
            int n = pthread_create(&_id, nullptr, Run, (void *)this);
            if (n != 0)
                return false;
            return true;
        }
        bool Join()
        {
            if (_joined)
            {
                int n = pthread_join(_id, nullptr);
                if (n != 0)
                    return false;
                return true;
            }
            return _status==TSTATUS::THREAD_STOP;
        }

        std::string Name()
        {
            return  _name;
        }
        ~Thread() {}

    private:
        static void *Run(void *obj)
        {
            Thread *self = static_cast<Thread *>(obj);
            self->_status = TSTATUS::THREAD_RUNNING;
            pthread_setname_np(self->_id, self->_name.c_str()); // 为当前线程取名字
            if (self->_joined == false)
                pthread_detach(pthread_self());
            self->_func();
            self->_status=TSTATUS::THREAD_STOP;
            return nullptr;
        }
        void SetName()
        {
            _name = "Thread-" + std::to_string(cnt++);
        }

    private:
        std::string _name;
        pthread_t _id;
        TSTATUS _status;
        bool _joined;
        work_t _func;
    };


    //获取当前线程名字
    std::string GetThreadNameFromNptl()
    {
        char buffer[16];
        pthread_getname_np(pthread_self(),buffer,sizeof(buffer));
        return buffer;
    }
}